package com.bizfx.collections
{
	import flash.events.EventDispatcher;
	import flash.utils.Dictionary;
	
	import com.bizfx.events.HashMapChangedEvent;
	
	[Event(name="hashMapChanged", type="com.bizfx.events.HashMapChangedEvent")]
	
	/**
	 * flex版的HashMap，参考java的hashmap来建立。
	 */
	public class HashMap extends EventDispatcher implements IMap{
		
		private var _keys:Array = new Array();
		private var props:Dictionary = new Dictionary();
		
		/**
		 * 构造函数
		 */
		public function HashMap() {
		}
		
		/**
		 * 清除Map中所有项。
		 */
		public function clear():void {
			this.props = new Dictionary();
			this._keys = new Array();
			this.dispatchEvent(new HashMapChangedEvent(HashMapChangedEvent.Changed_Type_Clear));
		}
		
		/**
		 * 是否含有某key的项。
		 */
		public function containsKey(key:Object):Boolean{
			return this.props[key] != null;
		}
		
		/**
		 * 是否含有某项。
		 */
		public function containsValue(value:Object):Boolean{
			var result:Boolean = false;
			var len:uint = this.size();
			if(len > 0){
				for(var i:uint = 0 ; i < len ; i++){
					if(this.props[this._keys[i]] == value) 
						return true;
				}
			}
			return false;
		}
		
		/**
		 * 通过key获取某项。
		 */
		public function get(key:Object):Object{
			return this.props[key];
		}
		
		/**
		 * 向Map中添加某项。
		 */
		public function put(key:Object,value:Object):Object{
			var result:Object = null;
			if(this.containsKey(key)){
				result = this.get(key);
				this.props[key] = value;
				this.dispatchEvent(new HashMapChangedEvent(HashMapChangedEvent.Changed_Type_Modify));
			}else{
				this.props[key] = value;
				this._keys.push(key);
				this.dispatchEvent(new HashMapChangedEvent(HashMapChangedEvent.Changed_Type_Add));
			}
			return result;
		}
		public function remove(key:Object):Object{
			var result:Object = null;
			if(this.containsKey(key)){
				delete this.props[key];
				var index:int = this._keys.indexOf(key);
				if(index > -1){
					this._keys.splice(index,1);
				}
				this.dispatchEvent(new HashMapChangedEvent(HashMapChangedEvent.Changed_Type_Remove));
			}
			return result;
		}
		public function putAll(map:IMap):void{
			this.clear();
			var len:uint = map.size();
			if(len > 0){
				var arr:Array = this._keys.keys;
				for(var i:uint=0;i<len;i++){
					this.put(arr[i],map.get(arr[i]));
				}
			}
		}
		public function size():uint{
			return this._keys.length;
		}
		public function isEmpty():Boolean{
			return this._keys.length < 1;
		}
		public function values():Array{
			var result:Array = new Array();
			var len:uint = this.size();
			if(len > 0){
				for(var i:uint = 0;i<len;i++){
					result.push(this.props[this._keys[i]]);
				}
			}
			return result;
		}
		public function keys():Array{
			return this._keys;
		}
	}
}